//////////////////////////////////////////////////////////////////////////////////
//	Copyright 2011 by Yosef Grabivker, ryuho@homenetworksoft.com
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//////////////////////////////////////////////////////////////////////////////////

#include <wx/wx.h>
#include <wx/translation.h>
#include <wx/regex.h>
#include "eventmanager.h"

static SEARCHFIELD sf[]=
{
	{ cSearchTypeString,	cRCEventFieldRawData,		_("Raw Data")				},
	{ cSearchTypeString,	cRCEventFieldMAC,			_("MAC")					},
	{ cSearchTypeString,	cRCEventFieldIP,			_("IP")						},
	{ cSearchTypeString,	cRCEventFieldTTL,			_("TTL(sec)")				},
	{ cSearchTypeString,	cRCEventFieldState,			_("State")					},
	{ cSearchTypeString,	cRCEventFieldProtocol,		_("Protocol")				},

	{ cSearchDateTime,		cRCEventFieldEventTime,		_("Time")					},
	{ cSearchTypeNumeric,	cRCEventCurResourceLevel,	_("Resourse Current Level") },
	{ cSearchTypeNumeric,	cRCEventMaxResourceLevel,	_("Resourse Maximum Level")	},
	{ cSearchTypeNumeric,	cRCEventResourceUsageLevel,	_("Resourse Usage Level(percent)")	},
};


CEventManager::CEventManager(void)
{
}

CEventManager::~CEventManager(void)
{
}

void CEventManager::AddEvent(const RCEVENT& evnt)
{
	for (size_t i=0;i<m_actions.size();i++)
	{
		const EVENTACTION& action = m_actions[i];

		if ( action.cEventID == evnt.cEventID )
		{
			CheckAction(action, evnt);
		}
	}
}

void CEventManager::CheckAction(const EVENTACTION& action, const RCEVENT& evnt)
{
	wxString strVal;

	for (size_t j=0;j<sizeof(sf)/sizeof(sf[0]);j++)
	{
		strVal = FieldToString( sf[j].iFieldID, evnt );

		if ( Match(action.filter.filterDef, sf[j], strVal) )
		{
			
		}
	}
}

bool CEventManager::Match(const FIELDRULESET& rlSet, const SEARCHFIELD& sf,
						  const wxString& strVal) const
{
	bool bRes(false);

	try
	{
		for ( size_t i=0;i<rlSet.size();i++ )
		{
			if ( sf.iFieldID == rlSet[i].iFieldID )
			{
				bRes|= ApplyRule(rlSet[i], sf, strVal);
			}
		}
	}
	catch(...)
	{
	}

	return bRes;
}

bool  CEventManager::ApplyRule(const FILTERFIELDRULE& rule, const SEARCHFIELD& sf,
							   const wxString& strVal) const
{
	bool bRes(true);

	switch( rule.rule )
	{
		case cFilterRuleAny:
		break;
			
		case cFilterRuleBigger:
			bRes = strVal>rule.strVal;
		break;

		case cFilterRuleBiggerOrEq:
			bRes = strVal>=rule.strVal;
		break;

		case cFilterRuleEq:
			bRes = strVal==rule.strVal;
			bRes|= strVal.Matches(rule.strVal);
		break;

		case cFilterRuleNotEq:
			bRes = strVal!=rule.strVal;
			bRes&= !strVal.Matches(rule.strVal);
		break;

		case cFilterRuleSmaller:
			bRes = strVal<rule.strVal;
		break;

		case cFilterRuleSmallerOrEq:
			bRes = strVal<=rule.strVal;
		break;

		case cFilterRuleRegExp:
		{
			wxRegEx regexp(rule.strVal, wxRE_DEFAULT);
			bRes = regexp.Matches(strVal);
		}
		break;
	}

	return bRes;
}



void CEventManager::ExecuteAction(const EVENTACTION& action, const RCEVENT& evnt)
{
	if ( action.iActions & cRCActionLog )
	{
		LogAction(action, evnt);
	}
	else
	if ( action.iActions & cRCActionRun )
	{
		RunAction(action, evnt);
	}
	else
	if ( action.iActions & cRCActionSendToRouterCLI )
	{
		SendToRouterAction(action, evnt);
	}
	else
	if ( action.iActions & cRCActionSendToHTTP )
	{
		SendToHTTPAction(action, evnt);
	}
}

wxString CEventManager::FieldToString( int column, const RCEVENT& entry)
{
	wxString str;

	try
	{
		switch(column)
		{
			case cRCEventFieldRawData:
				str = entry.strRawEvent;
			break;

			case cRCEventFieldMAC:
				str = entry.strMAC;
			break;

			case cRCEventFieldIP:
				str = entry.strMAC;
			break;

			case cRCEventFieldTTL:
				str = wxString::Format(wxT("%u"), entry.stTTL);
			break;

			case cRCEventFieldState:
				str = entry.strState;
			break;

			case cRCEventFieldProtocol:
				str = entry.strProtocol;
			break;

			case cRCEventFieldEventTime:
			{
				wxDateTime dt(entry.tEvent);
				str = dt.Format(_("%c"));
			}
			break;

			case cRCEventCurResourceLevel:
			{
				str = wxString::Format(wxT("%u"), entry.stCurLevel);
			}
			break;

			case cRCEventMaxResourceLevel:
			{
				str = wxString::Format(wxT("%u"), entry.stMAXLevel);
			}
			break;

			case cRCEventResourceUsageLevel:
			{
				size_t stUsage(0);

				if ( entry.stMAXLevel )
				{
					stUsage = (100*entry.stCurLevel)/entry.stMAXLevel;
				}

				str = wxString::Format(wxT("%u"), stUsage);
			}
		}
	}
	catch (...)
	{

	}

	return str;
}

/////////////////////////////////////////////////////////////////////////////////
void CEventManager::LogAction(const EVENTACTION& action, const RCEVENT& evnt)
{
}

void CEventManager::RunAction(const EVENTACTION& action, const RCEVENT& evnt)
{
}

void CEventManager::SendToRouterAction(const EVENTACTION& action, const RCEVENT& evnt)
{
}

void CEventManager::SendToHTTPAction(const EVENTACTION& action, const RCEVENT& evnt)
{
}
